package result

import (
	"fmt"
)

type MyCode interface {
	// ResultType returns the integer number of current error code.
	ResultType() int

	// Description returns the brief message for current error code.
	Description() string

	// Detail returns the detailed information of current error code,
	// which is mainly designed as an extension field for error code.
	Detail() interface{}
}

// myLocalCode is an implement for interface MyCode for internal usage only.
type myLocalCode struct {
	resultType  int         // Result type, usually an integer.
	description string      // Brief description.
	detail      interface{} // As type of interface, it is mainly designed as an extension field for error code.
}

// ResultType returns the integer number of current code.
func (c myLocalCode) ResultType() int {
	return c.resultType
}

// Description returns the brief description for current error code.
func (c myLocalCode) Description() string {
	return c.description
}

// Detail returns the detailed information of current error code,
// which is mainly designed as an extension field for error code.
func (c myLocalCode) Detail() interface{} {
	return c.detail
}

// String returns current error code as a string.
func (c myLocalCode) String() string {
	if c.detail != nil {
		return fmt.Sprintf(`%d:%s %v`, c.resultType, c.description, c.detail)
	}
	if c.description != "" {
		return fmt.Sprintf(`%d:%s`, c.resultType, c.description)
	}
	return fmt.Sprintf(`%d`, c.resultType)
}

var (
	CodeOK              = myLocalCode{3, "操作成功", nil} // No error code specified.
	CodeInternalError   = myLocalCode{4, "操作引发错误", nil}
	CodeNotAuthorized   = myLocalCode{6, "未验证", nil}
	CodeUnAuthenticated = myLocalCode{7, "未授权", nil}
)

func New(resultType int, description string, detail interface{}) MyCode {
	return myLocalCode{
		resultType:  resultType,
		description: description,
		detail:      detail,
	}
}
